package com.atwisdom.star.service.production.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.atwisdom.star.common.util.JsonUtil;
import com.atwisdom.star.common.vo.ActionData;
import com.atwisdom.star.common.vo.JsonResult;
import com.atwisdom.star.common.vo.ResultInfo;
import com.atwisdom.star.core.bsl.modelClass.hier.impl.HierInstanceBslServiceImpl;
import com.atwisdom.star.core.bsl.modelClass.tank.Impl.TankInstanceBslServiceImpl;
import com.atwisdom.star.core.dao.pojo.modelClass.hier.HierInstance;
import com.atwisdom.star.core.dsl.modelClass.hier.Impl.HierInstanceDslServiceImpl;
import com.atwisdom.star.core.dsl.modelClass.logic.Impl.LogicInstanceDslServiceImpl;
import com.atwisdom.star.exception.pojo.BusinessException;
import com.atwisdom.star.service.business.Tank;
import com.atwisdom.star.service.production.StorehouseService;
import com.atwisdom.star.service.util.InstanceDataUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName: StorehouseServiceImpl
 * @ Description:
 * @author:王红艳
 * @date: 2024/05/30 11:00
 */
@Service
public class StorehouseServiceImpl implements StorehouseService {
    @Autowired
    private HierInstanceDslServiceImpl hierInstanceDslServiceImpl;

    @Autowired
    private HierInstanceBslServiceImpl hierInstanceBslServiceImpl;

    @Autowired
    private LogicInstanceDslServiceImpl logicInstanceDslServiceImpl;

    @Autowired
    private TankInstanceBslServiceImpl tankInstanceBslServiceImpl;

    private final String storeClassName = "StorehouseConfig";
    private final String storeType = "staticLogic";
    private final String storeModel = "staticLogic";
    private final String tankClassName = "Tank";
    private final String tankType = "tank";
    private final String tankModel = "tank";

    /**
     * 新增仓库
     * @param data 仓库数据
     * @return 仓库数据
     * @throws BusinessException
     */
    @Override
    @Transactional
    public ResultInfo<?> addStorehouse(JSONObject data) throws BusinessException{
        HierInstance storehouseInstance = hierInstanceDslServiceImpl.addChild(data);
        JSONObject storehouseJson = hierInstanceDslServiceImpl.convertToJson(storehouseInstance);
        int line = storehouseJson.getJSONObject("values").getInteger("line");
        int column = storehouseJson.getJSONObject("values").getInteger("column");
        List<JSONObject> list = new ArrayList<>();
        for(int i=1;i<line+1;i++){
            for (int j=1;j<column+1;j++){
                list.add(JsonUtil.buildJson(new Object[]{"containerModel",storehouseInstance.getContainerModel(),
                        "containerId",storehouseInstance.getContainerId(),
                        "parentId",storehouseInstance.getNodeId(),
                        "values",JsonUtil.buildJson(new Object[]{"line",i,"column",j})
                }));
            }
        }
        hierInstanceDslServiceImpl.addChild(list);
        return JsonResult.success(storehouseJson);
    }

    /**
     * 更新仓库
     * @param data 仓库数据
     * @return 仓库数据
     * @throws BusinessException
     */
    @Override
    @Transactional
    public ResultInfo<?> updateStorehouse(JSONObject data) throws BusinessException{
        String nodeId = JsonUtil.get(data,"nodeId");
        List<HierInstance>  hierInstancesList = hierInstanceDslServiceImpl.query(storeModel,storeClassName,"");
        HierInstance oldStorehouse = InstanceDataUtil.getHierInstanceByNodeId(hierInstancesList,nodeId);
        if(null==oldStorehouse){
            return JsonResult.error(500,"不存在库位信息！");
        }
        List<HierInstance> filterChildList = new ArrayList<>();
        InstanceDataUtil.getChildrenByNodeId(hierInstancesList,nodeId,filterChildList);
        List<JSONObject> childList = hierInstanceDslServiceImpl.convertToJson(filterChildList);
        JSONObject oldStorehouseJson = hierInstanceDslServiceImpl.convertToJson(oldStorehouse);
        HierInstance storehouseInstance = hierInstanceDslServiceImpl.addChild(data);
        JSONObject storehouseJson = hierInstanceDslServiceImpl.convertToJson(storehouseInstance);
        dealAddChildList(oldStorehouseJson,storehouseJson,storehouseInstance);
        dealDeleteChildList(oldStorehouseJson,storehouseJson,childList);
        return JsonResult.success(storehouseJson);
    }

    /**
     * 删除仓库
     * @param data 仓库数据
     * @return 仓库数据
     * @throws BusinessException
     */
    @Override
    @Transactional
    public ResultInfo<?> deleteStorehouse(JSONObject data) throws BusinessException{
        String nodeId = JsonUtil.get(data,"nodeId");
        List<HierInstance>  hierInstancesList = hierInstanceDslServiceImpl.query(storeModel,storeClassName,"");
        List<HierInstance> filterList = InstanceDataUtil.getChildrenAndMeByNodeId(hierInstancesList,nodeId);
        if(CollectionUtil.isEmpty(filterList)){
            return JsonResult.error(500,"不存在仓库信息！");
        }
        List<Long> delIds = InstanceDataUtil.getIdsByHierList(filterList);
        List<Long> linkIds = InstanceDataUtil.getLinkIdsByHierList(filterList);
        if(CollectionUtil.isNotEmpty(linkIds)){
            return JsonResult.error(500,"仓库下库位被占用，不可删除！");
        }
        hierInstanceDslServiceImpl.deleteByIdList(delIds);
        return JsonResult.success(delIds);
    }
    /**
     * 分页查询，过滤掉被占用的数据
     * @param actionData 分页查询参数
     * @return 分页数据
     * @throws BusinessException
     */
    @Override
    public ResultInfo<?> queryTankNotLinkByPage(ActionData<JSONObject> actionData)  throws BusinessException {
        List<HierInstance> hierList = hierInstanceDslServiceImpl.queryLink(storeModel,storeClassName,null,tankModel,tankClassName,null);
        List<String> linkIds = InstanceDataUtil.listLongToListString(InstanceDataUtil.getLinkIdsByHierList(hierList));
        if(CollectionUtil.isNotEmpty(linkIds)){
            String conditon = actionData.getCondition();
            StringBuffer buffer = new StringBuffer(conditon+"&&id not in (");
            conditon = InstanceDataUtil.condJoin(buffer,linkIds,null);
            actionData.setCondition(conditon);
        }
        return tankInstanceBslServiceImpl.queryByPage(actionData);
    }

    /**
     * 入库 库位编码，库位名称，storeJson,linkId为入库的桶的id
     * @param storeJson 入库数据
     * @return hier更新后的json
     * @throws BusinessException
     */
    @Override
    @Transactional
    public ResultInfo<?> inputBound(JSONObject storeJson) throws BusinessException {
        Long linkId = storeJson.getLong("linkId");
        Tank tank = new Tank();
        tank.setTank(linkId);
        tank.inputBound(storeJson.getLong("id"),JsonUtil.get(storeJson,"values.sf_code"),JsonUtil.get(storeJson,"values.sf_name"));
        return JsonResult.success(hierInstanceDslServiceImpl.convertToJson(hierInstanceDslServiceImpl.addChild(storeJson)));
    }

    /**
     * 出库 库位编码，库位名称,
     * @param storeJson 出库数据
     * @return hier更新后的json
     * @throws BusinessException
     */
    @Override
    @Transactional
    public ResultInfo<?> outBound(JSONObject storeJson) throws BusinessException {
        Long linkId = storeJson.getJSONObject("link").getLong("linkId");
        storeJson.put("linkId",null);
        Tank tank = new Tank();
        tank.setTank(linkId);
        tank.outBound(storeJson.getLong("id"),JsonUtil.get(storeJson,"values.sf_code"),JsonUtil.get(storeJson,"values.sf_name"));
        return JsonResult.success(hierInstanceDslServiceImpl.convertToJson(hierInstanceDslServiceImpl.addChild(storeJson)));
    }

    /**
     * 根据hier数据查询下面的桶的数据
     * @param data
     * @return hier数据包含桶
     * @throws BusinessException
     */
    @Override
    @Transactional
    public ResultInfo<?> queryTankById(JSONObject data) throws BusinessException {
        String nodeId = JsonUtil.get(data,"nodeId");
        List<HierInstance>  hierInstancesList = hierInstanceDslServiceImpl.query(storeModel,storeClassName,"");
        List<HierInstance> filterList = InstanceDataUtil.getChildrenAndMeByNodeId(hierInstancesList,nodeId);
        List<JSONObject> hierJsonList = filterList.stream().map(hierInstance -> {
            Long linkId = hierInstance.getLinkId();
            JSONObject hierJson = hierInstanceDslServiceImpl.convertToJson(hierInstance);
            if(null!=linkId){
                JSONObject tankJson = logicInstanceDslServiceImpl.queryJsonById(linkId);
                hierJson.getJSONObject("link").put("values",tankJson.getJSONObject("values"));
            }
            return hierJson;
        }).collect(Collectors.toList());
        return JsonResult.success(hierJsonList);
    }



    /**
     * 处理库位新增
     * @param oldStorehouseJson 旧仓库数据
     * @param storehouseJson 新仓库数据json
     * @param storehouseInstance 新仓库数据
     */
    private void dealAddChildList(JSONObject oldStorehouseJson,JSONObject  storehouseJson,HierInstance storehouseInstance){
        int oldLine = oldStorehouseJson.getJSONObject("values").getInteger("line");
        int oldColumn = oldStorehouseJson.getJSONObject("values").getInteger("column");
        int line = storehouseJson.getJSONObject("values").getInteger("line");
        int column = storehouseJson.getJSONObject("values").getInteger("column");
        List<JSONObject> list = new ArrayList<>();
        for(int i=1;i<line+1;i++){
            for (int j=1;j<column+1;j++){
                if(i>oldLine||j>oldColumn){
                    list.add(JsonUtil.buildJson(new Object[]{"containerModel",storehouseInstance.getContainerModel(),
                            "containerId",storehouseInstance.getContainerId(),
                            "parentId",storehouseInstance.getNodeId(),
                            "values",JsonUtil.buildJson(new Object[]{"line",i,"column",j})
                    }));
                }
            }
        }
        hierInstanceDslServiceImpl.addChild(list);
    }

    /**
     * 处理库位删除
     * @param oldStorehouseJson 旧仓库数据
     * @param storehouseJson 新仓库数据json
     * @param childList 仓库下库位数据
     */
    private void dealDeleteChildList(JSONObject oldStorehouseJson,JSONObject  storehouseJson,List<JSONObject> childList){
        int oldLine = oldStorehouseJson.getJSONObject("values").getInteger("line");
        int oldColumn = oldStorehouseJson.getJSONObject("values").getInteger("column");
        int line = storehouseJson.getJSONObject("values").getInteger("line");
        int column = storehouseJson.getJSONObject("values").getInteger("column");
        List<Long> delIds = new ArrayList<>();
        for(int i=1;i<oldLine+1;i++){
            for (int j=1;j<oldColumn+1;j++){
                if(i>line||j>column){
                    int finalI = i;
                    int finalJ = j;
                    List<JSONObject> filterList = childList.stream().filter(jsonObject -> finalI ==jsonObject.getJSONObject("values").getIntValue("line")&& finalJ ==jsonObject.getJSONObject("values").getIntValue("column")).collect(Collectors.toList());
                    List<JSONObject> links = filterList.stream().filter(jsonObject -> null!=jsonObject.getLong("linkId")).collect(Collectors.toList());
                    if(CollectionUtil.isNotEmpty(links)){
                        throw new BusinessException("500","仓库下存在库位不可更改");
                    }
                    delIds.addAll(filterList.stream().map(jsonObject -> jsonObject.getLong("id")).collect(Collectors.toList()));
                }
            }
        }
        hierInstanceDslServiceImpl.deleteByIdList(delIds);
    }

}
